package reedSolomon;
import java.util.ArrayList;
import java.util.List;
import dataMode.QRData;

/**
 * RSBlock
 * @author Kazuhiko Arase 
 */
public class RSBlock {

	public static final int[][] RS_BLOCK_TABLE = {

		///Mode:
		
		///ECC:
		// L
		// M
		// Q
		// H
		
		//1		
		{7, 1, 19}, 		
		{10, 1, 16}, 		
		{13, 1,	13}, 		
		{17, 1, 9}, 		
		//2
		{10, 1, 34}, 		
		{16, 1, 28}, 		
		{22, 1, 22}, 		
		{28, 1, 16}, 		
		//3
		{15, 1, 55}, 		
		{26, 1, 44}, 		
		{18, 2, 17},		
		{22, 2, 13}, 		
		//4
		{20, 1, 80}, 		
		{18, 2, 32}, 		
		{26, 2, 24}, 		
		{16, 4, 9}, 		
		//5
		{26, 1, 108}, 		
		{24, 2, 43}, 		
		{18, 2, 15, 2, 16},
		{22, 2, 11, 2 , 12},
		//6
		{18, 2, 68},		
		{16, 4, 27}, 		
		{24, 4, 19}, 		
		{28, 4, 15}, 		
		//7
		{20, 2,	78}, 		
		{18, 4, 31}, 		
		{18, 2, 14, 4, 15},
		{26, 4, 13, 1, 14},
		//8
		{24, 2, 97}, 		
		{22, 2, 38, 2, 39},
		{22, 4, 18,	2, 19},
		{26, 4, 14,	2, 15},
		//9
		{30, 2, 116}, 		
		{22, 3, 36, 2, 37},
		{20, 4, 16, 4, 17},
		{24, 4, 12, 4, 13},
		//10
		{18, 2, 68, 2, 69},
		{26, 4, 43, 1, 44},
		{24, 6, 19, 2, 20},
		{28, 6, 15, 2, 16},
		//11
		{20, 4, 81}, 		
		{30, 1, 50, 4, 51},
		{28, 4, 22, 4, 23},
		{24, 3, 12, 8, 13},
		//12
		{24, 2, 92, 2, 93},
		{22, 6, 36, 2, 37},
		{26, 4, 20, 6, 21},
		{28, 7, 14, 4, 15},
		//13
		{26, 4, 107},
		{22, 8, 37, 1, 38},
		{24, 8, 20, 4, 21},
		{22, 12, 11, 4, 12},
		//14
		{30, 3, 115, 1, 116},
		{24, 4, 40, 5, 41},
		{20, 11, 16, 5, 17},
		{24, 11, 12, 5, 13},
		//15
		{22, 5, 87, 1, 88},
		{24, 5, 41, 5, 42},
		{30, 5, 24, 7, 25},
		{24, 11, 12, 7, 13},
		//16
		{24, 5, 98, 1, 99},
		{28, 7, 45, 3, 46},
		{24, 15, 19, 2, 20},
		{30, 3, 15, 13, 16},
		//17
		{28, 1, 107, 5, 108},
		{28, 10, 46, 1, 47},
		{28, 1, 22, 15, 23},
		{28, 2, 14, 17, 15},
		//18
		{30, 5, 120, 1, 121},
		{26, 9, 43, 4, 44},
		{28, 17, 22, 1, 23},
		{28, 2, 14, 19, 15},
		//19
		{28, 3, 113, 4, 114},
		{26, 3, 44, 11, 45},
		{26, 17, 21, 4, 22},
		{26, 9, 13, 16, 14},
		//20
		{28, 3, 107, 5, 108},
		{26, 3, 41, 13, 42},
		{30, 15, 24, 5, 25},
		{28, 15, 15, 10, 16},
		//21
		{28, 4, 116, 4, 117},
		{26, 17, 42},		
		{28, 17, 22, 6, 23},
		{30, 19, 16, 6, 17},
		//22
		{28, 2,	111, 7, 112},
		{28, 17, 46}, 		
		{30, 7, 24, 16, 25},
		{24, 34, 13}, 		
		//23
		{30, 4, 121, 5, 122},
		{28, 4, 47, 14, 48},
		{30, 11, 24, 14, 25},
		{30, 16, 15, 14, 16},
		//24
		{30, 6, 117, 4, 118},
		{28, 6, 45, 14, 46},
		{30, 11, 24, 16, 25},
		{30, 30, 16, 2, 17},
		//25
		{26, 8, 106, 4, 107},
		{28, 8, 47, 13, 48},
		{30, 7, 24, 22, 25},
		{30, 22, 15, 13, 16},
		//26
		{28, 10, 114, 2, 115},
		{28, 19, 46, 4, 47},
		{28, 28, 22, 6, 23},
		{30, 33, 16, 4, 17},
		//27
		{30, 8,	122, 4, 123},
		{28, 22, 45, 3, 46},
		{30, 8,	23, 26, 24},
		{30, 12, 15, 28, 16},
		//28
		{30, 3, 117, 10, 118},
		{28, 3, 45, 23, 46},
		{30, 4, 24, 31, 25},
		{30, 11, 15, 31, 16},
		//29
		{30, 7, 116, 7, 117},
		{28, 21, 45, 7, 46},
		{30, 1, 23, 37, 24},
		{30, 19, 15, 26, 16},
		//30
		{30, 5, 115, 10, 116},
		{28, 19, 47, 10, 48},
		{30, 15, 24, 25, 25},
		{30, 23, 15, 25, 16},
		//31
		{30, 13, 115, 3, 116},
		{28, 2,	46, 29, 47},
		{30, 42, 24, 1, 25},
		{30, 23, 15, 28, 16},
		//32
		{30, 17, 115}, 		
		{28, 10, 46, 23, 47},
		{30, 10, 24, 35, 25},
		{30, 19, 15, 35, 16},
		//33
		{30, 17, 115, 1, 116},
		{28, 14, 46, 21, 47},
		{30, 29, 24, 19, 25},
		{30, 11, 15, 46, 16},
		//34
		{30, 13, 115, 6, 116},
		{28, 14, 46, 23, 47},
		{30, 44, 24, 7, 25},
		{30, 59, 16, 1, 17},
		//35
		{30, 12, 121, 7, 122},
		{28, 12, 47, 26, 48},
		{30, 39, 24, 14, 25},
		{30, 22, 15, 41, 16},
		//36	
		{30, 6,	121, 14, 122},
		{28, 6, 47, 34, 48},
		{30, 46, 24, 10, 25},
		{30, 2,	15, 64, 16},
		//37
		{30, 17, 122, 4, 23},
		{28, 29, 46, 14, 47},
		{30, 49, 24, 10, 25},
		{30, 24, 15, 46, 16},
		//38
		{30, 4, 122, 18, 123},
		{28, 13, 46, 32, 47},
		{30, 48, 24, 14, 25},
		{30, 42, 15, 32, 16},
		//39
		{30, 20, 117, 4, 118},
		{28, 40, 47, 7, 48},
		{30, 43, 24, 22, 25},
		{30, 10, 15, 67, 16},
		//40
		{30, 19, 118, 6, 119},
		{28, 18, 47, 31, 48}, 	
		{30, 34, 24, 34, 25},
		{30, 20, 15, 61, 16},
	};

	private int totalCount;
	private int dataCount;
	
	private RSBlock(int totalCount, int dataCount) {
		this.totalCount = totalCount;
		this.dataCount  = dataCount;
	}
	
	public int getDataCount() {
		return dataCount;
	}
	
	public int getTotalCount() {
		return totalCount;
	}

	/*public static int getNbBlocksDataCodeWords(int version, int eccLvl) {
		return RS_BLOCK_TABLE[(version-1)+(eccLvl-1)][]
	}*/
	public static RSBlock[] getRSBlocks(int version, int errorCorrectLevel) {
		
		int[] rsBlock = getRsBlockTable(version, errorCorrectLevel);
		int length = (rsBlock.length-1) / 2;
		

		List<RSBlock> list = new ArrayList<RSBlock>();
						
		for (int i = 0; i < length; i++) {

			int count = rsBlock[i * 3 + 0];
			int totalCount = rsBlock[i * 3 + 1];
			int dataCount  = rsBlock[i * 3 + 2];

			for (int j = 0; j < count; j++) {
				list.add(new RSBlock(totalCount, dataCount) );	
			}
		}
		
		return (RSBlock[])list.toArray(new RSBlock[list.size() ]);
	}
	
	private static int[] getRsBlockTable(int version, int errorCorrectLevel) {

		try {

			switch(errorCorrectLevel) {
			case QRData.ERROR_CORR_LVL_L :
				return RS_BLOCK_TABLE[(version - 1) * 4 + 0];
			case QRData.ERROR_CORR_LVL_M :
				return RS_BLOCK_TABLE[(version - 1) * 4 + 1];
			case QRData.ERROR_CORR_LVL_Q :
				return RS_BLOCK_TABLE[(version - 1) * 4 + 2];
			case QRData.ERROR_CORR_LVL_H :
				return RS_BLOCK_TABLE[(version - 1) * 4 + 3];
			default :
				break;
			}
			
		} catch(Exception e) {
		}

		throw new IllegalArgumentException("version:" + version + " / eccLvl:" + errorCorrectLevel);
	}
}